﻿#define _CRT_SECURE_NO_WARNINGS


//百度之星2025初赛


//第四题:GCD Maximum
//给定一个正整数n。你需要找到，在所有使得gcd(1×1,2×2,⋯,×)
//gcd(1×p1, 2×p2, ⋯, n×pn) 的值尽可能大的1∼n 的排列p 中，字典序最小的排列p。
//
//其中：1∼n 的排列表示长度为n 且1∼n 均恰好出现一次的序列；gcd
//(1,2,⋯,)
//gcd(x1, x2, ⋯, xn) 表示1,2,⋯,x1, x2, ⋯, xn的最大公因数；- 对于两个1∼n 的排列a, b， a 的字典序比b 小，当且仅当存在一个正整数
//i，满足a 的前i−1 项与b 的前i−1 项均相同且ai< bi。
// 
//格式
//输入格式：
//输入一行，包含一个正整数n（2≤n≤10^5）。
//输出格式：
//输出一行，包含 n 个正整数，表示满足条件的1∼n 的排列p。
//样例 1
//输入：
// 2
// 输出：
// 2 1
// 
// 样例 2
// 输入：
// 3
// 输出：
// 1 2 3
// 
// 解释：第一组数据2 那么可能的组合有{1，2} {2，1} ，而{1，2} 就是计算{1 * 1 ，2 * 2} 的最大公因数gcd，而{2，1} 
//       就是计算{1 * 2 ，2 * 1} 的最大公因数。而如果这两组的最大公因数相同的情况下，那么就输出最小字典序的那一组序列（如当第二组输入3 的时候）

#include<iostream> 
#include<vector> 
#include<map> 

using namespace std;

typedef long long ll;
vector<vector<ll>> vv;
vector<ll> vv_num;

vector<ll> turn_Right(vector<ll> v)
{
    ll tmp = v.back();
    for (ll i = v.size() - 1; i > 0; i--)
        v[i] = v[i - 1];

    v[0] = tmp;
    vv.push_back(v);      //记录每次轮转后的数组

    return v;
}

ll Count_N(ll n)
{
    ll tmp = n;
    while (n - 1)
        tmp *= --n;

    return tmp;
}

ll MAX_num(vector<ll> v)
{
    ll max_num = 0;
    for (auto& e : v)
    {
        if (e > max_num)
            max_num = e;
    }
    return max_num;
}
void GCD(vector<ll> tmp, vector<ll> v2)
{
    vector<ll> v3; ll i = 0;
    for (auto& e : v2)
    {
        v3.push_back(e * tmp[i++]);
    }

    ll gcd = 1, flag = 0;
    ll max_num = MAX_num(v3);
    for (ll t = 1; t <= max_num; t++)
    {
        for (ll j = 0; j < tmp.size(); j++)
        {
            if (v3[j] % t != 0)
                flag = 1;
        }
        if (!flag)
            gcd = t;
    }
    vv_num.push_back(gcd);
}

void Math(vector<ll> v1, ll n, vector<ll> v2)
{
    vector<ll> tmp = v1;

    ll cnt = Count_N(n);
    while (cnt--)
    {
        GCD(tmp, v2);
        if(cnt)
            tmp = turn_Right(tmp);
    }

    ll max_gcd = MAX_num(vv_num);
    map<vector<ll>, ll>  map_vv;
    ll i = 0;
    for (auto& e : vv)
    {
        map_vv[e] = vv_num[i++];
    }

    vector<ll> tmp2;
    for (auto& e : map_vv)
    {
        if (e.second == max_gcd)
        {
            tmp2 = e.first;
            break;
        }
    }

    for (auto& e : tmp2)
        cout << e << ' ';
}

int main()
{
    ll n = 0;
    cin >> n;

    vector<ll> v1;
    for (ll i = 1; i <= n; i++)
        v1.push_back(i);

    vv.push_back(v1);

    Math(v1, n, v1);

    return 0;
}

























//第三题 yummy
// 给定一个长度为 
//�
//n 的序列
//�
//s 和一个正整数
//�
//k，其中
//�
//�
//∈
//−
//1
//,
//1
//s
//i
//​
//∈−1, 1，即
//�
//�
//s
//i
//​
//为
//−
//1
//−1 或
//1
//1。
//
//我们称一个长度为
//�
//n 的序列
//�
//v 是 Yummy 的，当且仅当序列
//�
//v 中的每个元素均为不大于
//�
//k 的非负整数，且满足：
//
//∑
//�
//=
//1
//�
//�
//�
//⋅
//�
//�
//⋅
//�
//�
//=
//0
//∑
//i = 1
//n
//​
//s
//i
//​
//⋅v
//i
//​
//⋅k
//i
//= 0
//
//即对于所有不大于
//�
//n 的正整数
//�
//i，
//�
//�
//⋅
//�
//�
//⋅
//�
//�
//s
//i
//​
//⋅v
//i
//​
//⋅k
//i
//之和为
//0
//0。
//
//你需要求出不同的长度为
//�
//n 的 Yummy 的序列
//�
//v 的数量。其中，我们称两个长度均为
//�
//m 的序列
//�
//,
//�
//a, b 是不同的，当且仅当存在至少一个不大于
//�
//m 的正整数
//�
//i 满足
//�
//�
//≠
//�
//�
//a
//i
//​
//
//
//= b
//i
//​
//。
//
//由于答案可能很大，所以你只需要求出答案对
//998244353
//998244353 取模的结果。
//
//格式
//输入格式：
//本题有多组测试数据。
//
//
//输入文件的第一行输入一个正整数
//�
//T（
//1
//≤
//�
//≤
//1
//0
//4
//1≤T≤10
//4
//） 表示测试数据组数。
//
//
//接下来，对于每一组测试数据：
//
//
//第一行输入两个正整数
//�
//n（
//2
//≤
//�
//≤
//5
//×
//1
//0
//5
//2≤n≤5×10
//5
//）和
//�
//k（
//2
//≤
//�
//≤
//1
//0
//9
//2≤k≤10
//9
//）。
//
//
//第二行输入
//�
//n 个整数
//�
//�
//s
//i
//​
//（
//�
//�
//∈
//−
//1
//,
//1
//s
//i
//​
//∈−1, 1）。
//
//
//保证对于单个测试点，所有
//�
//n 的和不超过
//5
//×
//1
//0
//5
//5×10
//5
//。
//
//
//输出格式：
//对于每组测试数据，输出一行一个整数表示答案对
//998244353
//998244353 取模的结果。
//
//
//样例 1
//输入：
//2
//5 2
//- 1 1 1 - 1 - 1
//8 100
//1 1 - 1 - 1 - 1 - 1 1 - 1
//复制
//输出：
//5
//16
// 
// 
// 
// 
// 
// 
//#include<iostream> 
//
//using namespace std;
//
//#define MOD 998244353
//typedef long long ll;
//
//
//int main()
//{
//    ll n = 0, k = 0;
//
//
//    return 0;
//}



